import hashlib

import pyrem_torq.script as _pts
import pyrem_torq.expression as _pte

def calc_md5(fileName):
    m = hashlib.md5()
    f = open(fileName, "rb")
    try:
        m.update(f.read())
    finally: f.close()
    return m.hexdigest()

def calc_md5_bytes(bytes):
    m = hashlib.md5()
    m.update(bytes)
    return m.hexdigest()

def expr_compile(exprStr, recursionAtMarker0=True, replaces=None):
    #exprs = my_compile(exprStr)
    return _pts.compile(exprStr, 
            recursionAtMarker0=recursionAtMarker0, 
            replaces=replaces)

def expr_replace(expr, replaces):
    _pte.assign_marker_expr(expr, replaces)
    return expr

class ReservedwordNode(_pte.TorqExpression):
    __slots__ = [ '__tbl' ]
    
    def extract_new_labels(self): return sorted(self.__tbl.itervalues())
    def extract_labels(self): return [ "word" ]
    
    def extractStringAndLabelPairs(self):
        return list(self.__tbl.iteritems())
    
    def __init__(self, labelAndStrings):
        self.__tbl = dict(( s, lbl ) for lbl, s in labelAndStrings)
    
    def _match_node(self, inpSeq, inpPos, lookAheadNode):
        if lookAheadNode[0] == "word":
            p = self.__tbl.get(lookAheadNode[1])
            if p is not None:
                node = lookAheadNode[:]
                node[0] = p
                return 1, ( node, ), ()
    
    def __eq__(self, right): 
        return isinstance(right, ReservedwordNode) and \
            sorted(self.__tbl.iteritems()) == sorted(right.__tbl.iteritems())
    
    def __repr__(self): return "LiteralBuildToNodeTable([%s])" % (",".join("(%s,%s)" % ( s, lbl ) for s, lbl in sorted(self.__tbl.iteritems())))
    def __hash__(self): return hash("LiteralBuildToNodeTable") + sum((hash(s) + hash(lbl)) for s, lbl in self.__tbl.iteritems())

    def required_node_literal_epsilon(self):
        return ( 'word', ), (), False

    @staticmethod
    def build(stringAndLabels): return ReservedwordNode(stringAndLabels)
